#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <iconv.h>

bool IsContainInvalidChar(const char* pszInputString)
{
    char szInputBuff[1024];
    char szOutputBuff[1024];
    char *pszInputBuff = szInputBuff;
    char *pszOutputBuff = szOutputBuff;
    size_t inBytesLeft = 0;
    size_t outBytesLeft = 0;

    // convert utf-8 to unicode-big
    iconv_t cd = iconv_open("utf-16be", "utf-8");
    if ((iconv_t)(-1) == cd)
    {
        printf("iconv_open failed");
        return true;
    }

    strncpy(szInputBuff, pszInputString, sizeof(szInputBuff) - 1);
    memset(szOutputBuff, 0, sizeof(szInputBuff));
    inBytesLeft = strlen(szInputBuff);
    outBytesLeft = sizeof(szOutputBuff) - 1;

    if ((size_t)(-1) == iconv(cd, &pszInputBuff, &inBytesLeft, &pszOutputBuff, &outBytesLeft))
    {
        printf("iconv failed");
        iconv_close(cd);
        return true;
    }

    // search for invalid unicode character 
    const unsigned char *p = (const unsigned char *)szOutputBuff;
    bool bFind = false;

    while (!(0 == *p && 0 == *(p + 1)))
    {
        if (*p > 0xe0)
        {
            bFind = true;   
            break;
        }
        p += 2;
    }

    iconv_close(cd);

    return bFind;
}

int main(void)
{
    // unicode 0xe785
    printf("%d\n", IsContainInvalidChar("\xee\x9e\x85"));
    // unicode 0xd7ff
    printf("%d\n", IsContainInvalidChar("\xed\x9f\xbf"));
    printf("%d\n", IsContainInvalidChar("坑跌"));
    return 0;
}
